from django.shortcuts import render, redirect, reverse, HttpResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.views.generic.base import View
from django.conf import settings
from django.contrib.auth.hashers import make_password, check_password
from utils.mixin_utils import LoginRequiredMixin
from django.http import JsonResponse

from .models import UserProfile, Banner
from operation.models import UserCourse, UserFavorite, Course, UserMessage
from organization.models import CourseOrg, Teacher
from .forms import LoginForm, RigisterForm, ForgetPwdForm, ModifyPwdForm, UploadImageForm

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import SignatureExpired
from celery_tasks.tasks import send_register_active_email
from pure_pagination import Paginator, EmptyPage, PageNotAnInteger


# Create your views here.
class CustomBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = UserProfile.objects.get(Q(username=username) | Q(email=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None


class RegisterView(View):
    def get(self, request):
        register_form = RigisterForm()
        return render(request, 'register.html', {'register_form': register_form})

    def post(self, request):
        register_form = RigisterForm(request.POST)
        if register_form.is_valid():
            email = register_form.cleaned_data.get('email')
            password = register_form.cleaned_data.get('password')
            has_user = UserProfile.objects.filter(email=email)
            if has_user:
                return render(request, 'register.html', {'register_form': register_form, 'msg': '用户已存在'})
            user = UserProfile.objects.create_user(username=email, email=email, password=password)
            user.is_active = 0
            user.save()
            # 加密用户的身份信息，生成激活token
            serializer = Serializer(settings.SECRET_KEY, 3600)
            info = {'confirm': user.id}
            token = serializer.dumps(info)  # bytes
            token = token.decode('utf8')  # 解码, str
            # 找其他人帮助我们发送邮件 celery:异步执行任务
            username = register_form.cleaned_data.get('email')
            email = register_form.cleaned_data.get('email')
            # 写入欢迎注册信息
            UserMessage.objects.create(user=user.id, message='欢迎注册慕学在线网')
            send_register_active_email.delay(email, username, token, 'register')
            # 返回应答,跳转首页
            return redirect(reverse('index'))
        else:
            return render(request, 'register.html', {'register_form': register_form})


# active/加密信息token
class ActiveView(View):
    def get(self, request, token):
        # 进行用户激活
        # 进行解密，获取要激活的用户信息
        try:
            serializer = Serializer(settings.SECRET_KEY, 3600)
            info = serializer.loads(token)
            # 获取待激活用户的id
            user_id = info['confirm']
            # 根据id获取用户信息
            user = UserProfile.objects.get(id=user_id)
            user.is_active = 1
            user.save()
            # 跳转到登录页面
            return redirect(reverse('login'))
        except Exception as e:
            return HttpResponse('邮箱激活失败')


class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        login_form = LoginForm(request.POST)
        if login_form.is_valid():
            user = authenticate(**login_form.cleaned_data)
            if user:
                login(request, user)
                return redirect(reverse('index'))
            else:
                return render(request, 'login.html', {"msg": "用户名或密码错误!"})
        else:
            return render(request, 'login.html', {'login_form': login_form})


class LogoutView(View):
    def get(self, request):
        logout(request)
        return redirect(reverse("index"))


class ForgerPwdView(View):
    def get(self, request):
        forgetpwd_form = ForgetPwdForm()
        return render(request, 'forgetpwd.html', {'forgetpwd_form': forgetpwd_form})

    def post(self, request):
        forgetpwd_form = ForgetPwdForm(request.POST)
        if forgetpwd_form.is_valid():
            email = forgetpwd_form.cleaned_data.get('email')
            try:
                user = UserProfile.objects.get(email=email)
            except Exception as e:
                return render(request, 'forgetpwd.html', {'forgetpwd_form': forgetpwd_form, 'msg': '用户不存在'})
            serializer = Serializer(settings.SECRET_KEY, 3600)
            info = {'confirm': user.id}
            token = serializer.dumps(info)  # bytes
            token = token.decode('utf8')  # 解码, str
            send_register_active_email.delay(email, email, token, 'forget')
            return HttpResponse('邮件发送成功,请注意查收!')
        else:
            return render(request, 'forgetpwd.html', {'forgetpwd_form': forgetpwd_form})


class ResetView(View):
    def get(self, request, token):
        try:
            serializer = Serializer(settings.SECRET_KEY, 3600)
            info = serializer.loads(token)
            # 获取待激活用户的id
            user_id = info['confirm']
            # 根据id获取用户信息
            user = UserProfile.objects.get(id=user_id)
            return render(request, 'password_reset.html', {'user': user})
        except Exception as e:
            return HttpResponse('重置链接无效')


class ModifyPwdView(View):
    def post(self, request):
        modify_form = ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            pwd1 = request.POST.get('password1', '')
            pwd2 = request.POST.get('password2', '')
            email = request.POST.get('email', '')
            if pwd1 != pwd2:
                return render(request, 'password_reset.html', {'email': email, 'msg': "密码不一致"})
            user = UserProfile.objects.get(email=email)
            user.password = make_password(pwd1)
            user.save()
            return redirect(reverse('login'))
        else:
            email = request.POST.get('email', '')
            return render(request, 'password_reset.html', {'email': email, 'modify_form': modify_form})


class UserInfoView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'usercenter-info.html')


class UploadImageView(LoginRequiredMixin, View):
    def post(self, request):
        image_form = UploadImageForm(request.POST, request.FILES, instance=request.user)
        if image_form.is_valid():
            image_form.save()
            return JsonResponse({'status': "success", 'msg': "修改成功"})
        else:
            return JsonResponse({'status': "fail", 'msg': "修改失败"})


class UpdatePwdView(View):
    def post(self, request):
        modify_form = ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            pwd1 = request.POST.get('password1', '')
            pwd2 = request.POST.get('password2', '')
            if pwd1 != pwd2:
                return JsonResponse({'status': "fail", 'msg': "两次密码不一致"})
            user = request.user
            user.password = make_password(pwd1)
            user.save()
            return JsonResponse({'status': "success", 'msg': "修改成功"})
        else:
            return JsonResponse(modify_form.errors)


class MyCourseView(LoginRequiredMixin, View):
    def get(self, request):
        user_courses = UserCourse.objects.filter(user=request.user)
        return render(request, 'usercenter-mycourse.html', {
            "user_courses": user_courses
        })


class MyFavOrgView(LoginRequiredMixin, View):
    def get(self, request):
        favs_orgs = UserFavorite.objects.filter(user=request.user, fav_type=2).values_list('fav_id', flat=True)
        org_list = CourseOrg.objects.filter(pk__in=list(favs_orgs))
        return render(request, 'usercenter-fav-org.html', {
            "org_list": org_list
        })


class MyFavTeacherView(LoginRequiredMixin, View):
    def get(self, request):
        favs_teacher = UserFavorite.objects.filter(user=request.user, fav_type=3).values_list('fav_id', flat=True)
        teacher_list = Teacher.objects.filter(pk__in=list(favs_teacher))
        return render(request, 'usercenter-fav-teacher.html', {
            "teacher_list": teacher_list
        })


class MyFavCourseView(LoginRequiredMixin, View):
    def get(self, request):
        favs_course = UserFavorite.objects.filter(user=request.user, fav_type=1).values_list('fav_id', flat=True)
        course_list = Course.objects.filter(pk__in=list(favs_course))
        return render(request, 'usercenter-fav-course.html', {
            "course_list": course_list
        })


class MyMessageView(LoginRequiredMixin, View):
    def get(self, request):
        all_message = UserMessage.objects.filter(user=request.user.id)
        all_unread_messages = UserMessage.objects.filter(user=request.user.id, has_read=False)
        for unread_messages in all_unread_messages:
            unread_messages.has_read = True
            unread_messages.save()

        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1

        # Provide Paginator with the request object for complete querystring generation
        p = Paginator(all_message, request=request, per_page=1)

        all_message = p.page(page)

        return render(request, 'usercenter-message.html', {
            'all_message': all_message
        })


class IndexView(View):
    def get(self, request):
        all_banners = Banner.objects.all().order_by('index')
        courses = Course.objects.filter(is_banner=False)[:6]
        banner_courses = Course.objects.filter(is_banner=True)[:3]
        course_orgs = CourseOrg.objects.all()[:15]
        return render(request, 'index.html', {
            "all_banners": all_banners,
            "courses": courses,
            "banner_courses": banner_courses,
            "course_orgs": course_orgs,
        })


def page_not_found(request, exception):
    # 全局404处理函数
    from django.shortcuts import render_to_response
    response = render_to_response('404.html')
    response.status_code = 404
    return response


def page_error(request):
    # 全局404处理函数
    from django.shortcuts import render_to_response
    response = render_to_response('500.html')
    response.status_code = 500
    return response
